home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 176-200 / disk_190 / nethack / twee.zoo / fight.c < prev    next >
C/C++ Source or Header  |  1988-07-22  |  19KB  |  705 lines

  1. /*    SCCS Id: @(#)fight.c    2.3     87/12/12
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3.  
  4. #include    <stdio.h>
  5. #include    "hack.h"
  6.  
  7. extern struct permonst li_dog, dog, la_dog;
  8. extern char *exclam(), *hcolor(), *xname();
  9. extern struct obj *mkobj_at();
  10. #ifdef KAA
  11. extern boolean stoned;
  12. extern boolean unweapon;
  13. extern char *nomovemsg, *defmonnam();
  14. extern struct monst *mkmon_at();
  15. #endif
  16. #ifdef RPH
  17. extern struct obj *mk_named_obj_at();
  18. #endif
  19.  
  20. static boolean far_noise;
  21. static long noisetime;
  22.  
  23. #ifdef STOOGES
  24. char random_joke[][30] = {"Why I ought a ...",
  25.             "You'll get what's comming!",
  26.             "I'll murder you!",
  27.             "I get no respect!",
  28.             "Right in the kisser!",
  29.             "Wait a minute!",
  30.             "Take it easy!",
  31.             "Alright already!",
  32.             "That's more like it!",
  33.             "Well excuse me!",
  34.             "Take that!",
  35.             "I'll fix you!",
  36.             "I'm sorry!",
  37.             "Your mama!",
  38.             "Shut up!",
  39.             "Listen you!",
  40.             "Pardon me!",
  41.             "Not that!",
  42.             "Quiet!",
  43.             "Relax!",
  44.             "Certainly!",
  45.             "Ouch!",
  46.             "What happened?",
  47.             "What was that for?",
  48.             "What's the matter with you?",
  49.             "Oh Yea?",
  50.             "Wise guy eh?",
  51.             "How about a knuckle sandwich?",
  52.             "You coward!",
  53.             "You rat you!",
  54.             "You chuckelhead!",
  55.             "You bonehead!",
  56.             "You numbskull!",
  57.             "Nyak Nyak Nyak ...",
  58.             "Woop Woop Woop Woop ..."};
  59. #define RAND_JOKE    35
  60. #endif
  61.  
  62. /* hitmm returns 0 (miss), 1 (hit), or 2 (kill) */
  63. hitmm(magr,mdef) register struct monst *magr,*mdef; {
  64. register struct permonst *pa = magr->data, *pd = mdef->data;
  65. int hit;
  66. schar tmp;
  67. boolean vis;
  68.     if(!magr || !mdef) return(0);           /* mike@genat */
  69.     if(index("Eauy", pa->mlet)) return(0);
  70.     if(magr->mfroz) return(0);              /* riv05!a3 */
  71.     tmp = pd->ac + pa->mlevel;
  72.     if(mdef->mconf || mdef->mfroz || mdef->msleep){
  73.         tmp += 4;
  74.         if(mdef->msleep) mdef->msleep = 0;
  75.     }
  76.     hit = (tmp > rnd(20));
  77.     if(hit) mdef->msleep = 0;
  78.     vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my));
  79.     if(vis){
  80.         char buf[BUFSZ];
  81.         if(mdef->mimic) seemimic(mdef);
  82.         if(magr->mimic) seemimic(magr);
  83.         (void) sprintf(buf,"%s %s", Monnam(magr),
  84.             hit ? "hits" : "misses");
  85.         pline("%s %s.", buf, monnam(mdef));
  86.     } else {
  87.         boolean farq = (dist(magr->mx, magr->my) > 15);
  88.         if(farq != far_noise || moves-noisetime > 10) {
  89.             far_noise = farq;
  90.             noisetime = moves;
  91.             pline("You hear some noises%s.",
  92.                 farq ? " in the distance" : "");
  93.         }
  94.     }
  95. #ifdef STOOGES
  96.     if (hit && magr->isstooge) {
  97.         if (!rn2(6) && !index("afgvyF",mdef->data->mlet)) {
  98.             if(vis)
  99.                 pline("%s is poked in the eye!", Monnam(mdef));
  100.             mdef->mcansee = 0;
  101.             mdef->mblinded += rnd(10);
  102.             if (mdef->mblinded <= 0) mdef->mblinded = 127;
  103.         } else if (vis && mdef->isstooge)
  104.             switch (rn2(100)) {
  105.             case 0 : pline("%s is shoved!", Monnam(mdef));
  106.                 break;
  107.             case 1 : pline("%s is kicked!", Monnam(mdef));
  108.                 break;
  109.             case 2 : pline("%s is slapped!", Monnam(mdef));
  110.                 break;
  111.             case 3 : pline("%s is slugged!", Monnam(mdef));
  112.                 break;
  113.             case 4 : pline("%s is punched!", Monnam(mdef));
  114.                 break;
  115.             case 5 : pline("%s is pinched!", Monnam(mdef));
  116.                 break;
  117.             case 6 : pline("But %s dodges!", monnam(mdef));
  118.                 break;
  119.             case 7 : pline("But %s ducks!", monnam(mdef));
  120.                 break;
  121.             case 8 : pline("%s gets a black eye!", Monnam(mdef));
  122.                 break;
  123.             case 9 : pline("%s gets a bloody nose!", Monnam(mdef));
  124.                 break;
  125.             case 10: pline("%s gets a broken tooth!", Monnam(mdef));
  126.                 break;
  127.             }
  128.         if (!rn2(2))
  129.             stoogejoke();
  130.     }
  131.     if (magr->isstooge && mdef->isstooge)
  132.         return(hit);    /* stooges don't damage each other */
  133. #endif
  134.     if(hit){
  135.         if(magr->data->mlet == 'c' && !magr->cham) {
  136.             magr->mhpmax += 3;
  137.             if(vis) pline("%s is turned to stone!", Monnam(mdef));
  138.             else if(mdef->mtame)
  139.      pline("You have a peculiarly sad feeling for a moment, then it passes.");
  140.             monstone(mdef);
  141.             hit = 2;
  142.         } else
  143.         if((mdef->mhp -= d(pa->damn,pa->damd)) < 1) {
  144.             magr->mhpmax += 1 + rn2(pd->mlevel+1);
  145.             if(magr->mtame && magr->mhpmax > 8*pa->mlevel){
  146.                 if(pa == &li_dog) magr->data = pa = &dog;
  147.                 else if(pa == &dog) magr->data = pa = &la_dog;
  148.             }
  149.             if(vis) pline("%s is killed!", Monnam(mdef));
  150.             else if(mdef->mtame)
  151.         pline("You have a sad feeling for a moment, then it passes.");
  152.             mondied(mdef);
  153.             hit = 2;
  154.         }
  155.         /* fixes a bug where max monster hp could overflow. */
  156.         if(magr->mhpmax <= 0) magr->mhpmax = 127;
  157.     }
  158. #ifdef KAA
  159.     if(hit == 1 && magr->data->mlet == 'Q') {
  160.         rloc(mdef);
  161.         if(vis && !cansee(mdef->mx,mdef->my))
  162.             pline("%s suddenly disappears!",Monnam(mdef));
  163.     }
  164. #endif
  165.     return(hit);
  166. }
  167.  
  168. /* drop (perhaps) a cadaver and remove monster */
  169. mondied(mdef) register struct monst *mdef; {
  170. register struct permonst *pd = mdef->data;
  171. #ifdef KOPS
  172.     if(pd->mlet != 'K')
  173. #endif
  174.     {
  175. /* #if defined(ROCKMOLE) && defined(KJSMODS) */
  176. #ifdef ROCKMOLE
  177. # ifdef KJSMODS
  178.         /* if a giant rat is killed by a monster, do not make a
  179.          * corpse (like Keystone Kops above). */
  180.         if(!(pd->mlet == 'r' && dlevel < 4))
  181. # endif
  182. #endif
  183.         if(!(pd->mlet == '&' && mdef->isdjinni))  /* no djinni corpse */
  184.         if(!(pd->mlet == 'G' && mdef->isgremlin)) /* no gremlin corpse */
  185.         if(letter(pd->mlet) && rn2(3)) {
  186.             if (pd->mlet == '1') panic("mondied: making obj '1'");
  187. #ifndef RPH
  188.             (void) mkobj_at(pd->mlet,mdef->mx,mdef->my);
  189. #else
  190.             (void) mk_named_obj_at(pd->mlet,mdef->mx,mdef->my,
  191.                        NAME(mdef), mdef->mnamelth);
  192. #endif
  193.             if(cansee(mdef->mx,mdef->my)){
  194.             unpmon(mdef);
  195.             atl(mdef->mx,mdef->my,fobj->olet);
  196.             }
  197.             stackobj(fobj);
  198.         }
  199.         mondead(mdef);
  200.     }
  201. }
  202.  
  203. /* drop a rock and remove monster */
  204. monstone(mdef)
  205.     register struct monst *mdef;
  206. {
  207.     extern char mlarge[];
  208.     if(index(mlarge, mdef->data->mlet))
  209.         mksobj_at(ENORMOUS_ROCK, mdef->mx, mdef->my);
  210.     else
  211.         mksobj_at(ROCK, mdef->mx, mdef->my);
  212.     if(cansee(mdef->mx, mdef->my)){
  213.         unpmon(mdef);
  214.         atl(mdef->mx,mdef->my,fobj->olet);
  215.     }
  216.     mondead(mdef);
  217. }
  218.  
  219.  
  220. fightm(mtmp)
  221.     register struct monst *mtmp;
  222. {
  223. register struct monst *mon;
  224.  
  225.     for(mon = fmon; mon; mon = mon->nmon)
  226.         if(mon != mtmp) {
  227.         if(DIST(mon->mx,mon->my,mtmp->mx,mtmp->my) < 3)
  228.             if(rn2(4))  return(hitmm(mtmp,mon));
  229.         }
  230.     return(-1);
  231. }
  232.  
  233. /* u is hit by sth, but not a monster */
  234. thitu(tlev,dam,name)
  235.     register tlev,dam;
  236.     register char *name;
  237. {
  238.     char buf[BUFSZ];
  239.  
  240.     setan(name,buf);
  241.     if(u.uac + tlev <= rnd(20)) {
  242.         if(Blind) pline("It misses.");
  243.         else pline("You are almost hit by %s!", buf);
  244.         return(0);
  245.     } else {
  246.         if(Blind) pline("You are hit!");
  247.         else pline("You are hit by %s!", buf);
  248.         losehp(dam,name);
  249.         return(1);
  250.     }
  251. }
  252.  
  253. #ifdef KAA
  254. char mlarge[] = "bCDdegIlmnoPSsTUwY',&9";
  255. #else
  256. char mlarge[] = "bCDdegIlmnoPSsTUwY',&";
  257. #endif
  258.  
  259. boolean
  260. hmon(mon,obj,thrown)    /* return TRUE if mon still alive */
  261. register struct monst *mon;
  262. register struct obj *obj;
  263. register thrown;
  264. {
  265.     register tmp;
  266.     boolean hittxt = FALSE;
  267.  
  268. #ifdef KAA
  269.     stoned = FALSE;     /* this refers to the thing hit, not you */
  270. #endif
  271.     if(!obj){
  272. #ifdef KAA
  273. /* Note that c, y, and F can never wield weapons anyway */
  274.       if (u.usym == 'c' && mon->data->mlet != 'c') {
  275.            pline("You turn %s to stone!", monnam(mon));
  276.            stoned = TRUE;
  277.            xkilled(mon,0);
  278.            return(FALSE);
  279.       } else if (u.usym == 'y' && mon->data->mlet != 'y') {
  280.            pline("%s is blinded by your flash of light!",Monnam(mon));
  281.            if (!mon->mblinded) {
  282.             mon->mblinded += rn2(25);
  283.             mon->mcansee = 0;
  284.            }
  285.            rehumanize();
  286.            return(TRUE);
  287.       } else if (u.usym == 'F') {
  288.            pline("You explode!");
  289.            if (!index("gFY",mon->data->mlet)) {
  290.             pline("%s gets blasted!", Monnam(mon));
  291.             mon->mhp -= d(6,6);
  292.             rehumanize();
  293.             if (mon->mhp <= 0) {
  294.              killed(mon);
  295.              return(FALSE);
  296.             } else return(TRUE);
  297.            } else {
  298.             pline("The blast doesn't seem to affect %s.", monnam(mon));
  299.             rehumanize();
  300.             return(TRUE);
  301.            }
  302.       } else if (index("P,'", u.usym) && u.uhunger < 1500
  303.           && !u.uswallow && mon->data->mlet != 'c') {
  304.            static char msgbuf[BUFSZ];
  305.            pline("You swallow %s whole!", monnam(mon));
  306.            u.uhunger += 20*mon->mhpmax;
  307.            newuhs(FALSE);
  308.            xkilled(mon,2);
  309.            if (tmp = mon->mhpmax/5) {
  310.             nomul(-tmp);
  311.             (void)sprintf(msgbuf, "You finished digesting %s.",
  312.              monnam(mon));
  313.             nomovemsg = msgbuf;
  314.            }
  315.            return(FALSE);
  316.       } else if (u.usym != '@') {
  317.            if (u.usym == '&' && !rn2(5)) {
  318.             struct monst *dtmp;
  319.             pline("Some hell-p has arrived!");
  320.             if((dtmp = mkmon_at('&',u.ux,u.uy)))
  321.             (void)tamedog(dtmp,(struct obj *)0);
  322.            }
  323.            tmp = d(mons[u.umonnum].damn, mons[u.umonnum].damd);
  324.       } else
  325. #endif
  326.         tmp = rnd(2);   /* attack with bare hands */
  327. #ifdef KAA
  328.         if (mon->data->mlet == 'c' && !uarmg && u.usym != 'c'){
  329. #else
  330.         if(mon->data->mlet == 'c' && !uarmg){
  331. #endif
  332.             pline("You hit the cockatrice with your bare hands.");
  333.             pline("You turn to stone ...");
  334.             done_in_by(mon);
  335.         }
  336.     } else if(obj->olet == WEAPON_SYM || obj->otyp == PICK_AXE) {
  337.         if(obj == uwep && (obj->otyp > SPEAR || obj->otyp < BOOMERANG))
  338.         tmp = rnd(2);
  339.         else {
  340.         if(index(mlarge, mon->data->mlet)) {
  341.             tmp = rnd(objects[obj->otyp].wldam);
  342.             switch (obj->otyp) {
  343.             case SLING_BULLET:
  344.             case CROSSBOW_BOLT:
  345.             case MORNING_STAR:
  346.             case PARTISAN:
  347.             case BROAD_SWORD:    tmp += 1; break;
  348.  
  349.             case FLAIL:
  350.             case RANSEUR:
  351.             case VOULGE:        tmp += rnd(4); break;
  352.  
  353.             case HALBERD:
  354.             case SPETUM:        tmp += rnd(6); break;
  355.  
  356.             case BARDICHE:
  357.             case TRIDENT:        tmp += d(2,4); break;
  358.  
  359.             case TWO_HANDED_SWORD:
  360.             case KATANA:        tmp += d(2,6); break;
  361.             }
  362.         } else {
  363.             tmp = rnd(objects[obj->otyp].wsdam);
  364.             switch (obj->otyp) {
  365.             case SLING_BULLET:
  366.             case CROSSBOW_BOLT:
  367.             case MACE:
  368.             case FLAIL:
  369.             case SPETUM:
  370.             case TRIDENT:        tmp += 1; break;
  371.  
  372.             case BARDICHE:
  373.             case BILL_GUISARME:
  374.             case GUISARME:
  375.             case LUCERN_HAMMER:
  376.             case MORNING_STAR:
  377.             case RANSEUR:
  378.             case BROAD_SWORD:
  379.             case VOULGE:        tmp += rnd(4); break;
  380.             }
  381.         }
  382.         tmp += obj->spe;
  383. #ifdef KAA
  384.         if(obj->olet == WEAPON_SYM && obj->dknown && index("VWZ &",
  385.                 mon->data->mlet)) tmp += rn2(4);
  386. #endif
  387.         if(!thrown && obj == uwep && obj->otyp == BOOMERANG
  388.          && !rn2(3)){
  389.           pline("As you hit %s, the boomerang breaks into splinters.",
  390.                 monnam(mon));
  391.             freeinv(obj);
  392.             setworn((struct obj *) 0, obj->owornmask);
  393.             obfree(obj, (struct obj *) 0);
  394.             tmp++;
  395.         }
  396.         }
  397. #ifdef BVH
  398.         if(!strcmp(ONAME(obj), "Excalibur")) tmp += rnd(10);
  399.         else
  400. #endif
  401.         if(obj->otyp == KATANA
  402.            && !strcmp(ONAME(obj), "Snickersnee")) tmp += rnd(5);
  403.  
  404.         else if(mon->data->mlet == 'O' && obj->otyp == TWO_HANDED_SWORD
  405.             && !strcmp(ONAME(obj), "Orcrist"))  tmp += rnd(10);
  406.  
  407.         else if((obj->otyp == SHORT_SWORD || obj->otyp == DAGGER)
  408.            && !strcmp(ONAME(obj), "Sting")) tmp += rnd(5);
  409.  
  410.     } else    switch(obj->otyp) {
  411.         case HEAVY_IRON_BALL:
  412.             tmp = rnd(25); break;
  413.         case ENORMOUS_ROCK:
  414.             tmp = rnd(20); break;
  415. #ifdef RPH
  416.         case MIRROR:
  417.             pline("You break your mirror.  That's bad luck!");
  418.             change_luck(-2);
  419.             freeinv(obj);
  420.             if(obj->owornmask)
  421.                 setworn((struct obj *) 0, obj->owornmask);
  422.             obfree(obj, (struct obj *) 0);
  423.             return(TRUE);
  424. #endif
  425.         case EXPENSIVE_CAMERA:
  426.     pline("You succeed in destroying your camera. Congratulations!");
  427.             freeinv(obj);
  428.             if(obj->owornmask)
  429.                 setworn((struct obj *) 0, obj->owornmask);
  430.             obfree(obj, (struct obj *) 0);
  431.             return(TRUE);
  432.         case DEAD_COCKATRICE:    /* fixed by polder@cs.vu.nl */
  433.             pline("You hit %s with the cockatrice corpse.",
  434.                 monnam(mon));
  435.             if(mon->data->mlet == 'c') {
  436.                 tmp = 1;
  437.                 hittxt = TRUE;
  438.                 break;
  439.             }
  440.             pline ("%s is turned to stone!", Monnam(mon));
  441. #ifdef KAA
  442.             stoned = TRUE;
  443.             xkilled(mon,0);
  444. #else
  445.             killed(mon);
  446. #endif
  447.             return(FALSE);
  448.         case CLOVE_OF_GARLIC:        /* no effect against demons */
  449.             if(index(UNDEAD, mon->data->mlet))
  450.                 mon->mflee = 1;
  451.             tmp = 1;
  452.             break;
  453.         default:
  454.             /* non-weapons can damage because of their weight */
  455.             /* (but not too much) */
  456.             tmp = obj->owt/10;
  457.             if(tmp < 1) tmp = 1;
  458.             else tmp = rnd(tmp);
  459.             if(tmp > 6) tmp = 6;
  460.         }
  461.  
  462.     /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG) */
  463.  
  464.     tmp += u.udaminc + dbon();
  465.     if(u.uswallow) {
  466.         if((tmp -= u.uswldtim) <= 0) {
  467.             pline("Your arms are no longer able to hit.");
  468.             return(TRUE);
  469.         }
  470.     }
  471.     if(tmp < 1) tmp = 1;
  472.     mon->mhp -= tmp;
  473.     if(mon->mhp < 1) {
  474.         killed(mon);
  475.         return(FALSE);
  476.     }
  477.     if(mon->mtame && (!mon->mflee || mon->mfleetim)) {
  478.         mon->mflee = 1;         /* Rick Richardson */
  479.         mon->mfleetim += 10*rnd(tmp);
  480.     }
  481.  
  482.     if(!hittxt) {
  483.         if(thrown)
  484.             /* this assumes that we cannot throw plural things */
  485.             hit( xname(obj)  /* or: objects[obj->otyp].oc_name */,
  486.                 mon, exclam(tmp) );
  487.         else if(Blind)
  488.             pline("You hit it.");
  489.         else
  490.             pline("You hit %s%s", monnam(mon), exclam(tmp));
  491.     }
  492.  
  493.     if(u.umconf && !thrown) {
  494.         if(!Blind) {
  495.             pline("Your hands stop glowing %s.",
  496.             Hallucination ? hcolor() : "blue");
  497.         }
  498.         if (!resist(mon, '+', 0, NOTELL)) mon->mconf = 1;
  499.         if(!mon->mfroz && !mon->msleep && !Blind && mon->mconf)
  500.             pline("%s appears confused.",Monnam(mon));
  501.         u.umconf = 0;
  502.     }
  503.     if(!thrown && rn2(2) && index("VW",u.usym) &&
  504.        !index("VW",mon->data->mlet)){
  505.         int tmp=d(2,6);
  506.         pline("%s suddenly seems weaker!",Monnam(mon));
  507.         mon->mhpmax -= tmp;
  508.         if ((mon->mhp -= tmp) <= 0) {
  509.             pline("%s dies!",Monnam(mon));
  510.             xkilled(mon,0);
  511.             return(FALSE);
  512.         }
  513.     }
  514.     return(TRUE);   /* mon still alive */
  515. }
  516.  
  517. /* try to attack; return FALSE if monster evaded */
  518. /* u.dx and u.dy must be set */
  519. attack(mtmp)
  520. register struct monst *mtmp;
  521. {
  522.     schar tmp;
  523.     boolean malive = TRUE;
  524.     register struct permonst *mdat;
  525.     mdat = mtmp->data;
  526.  
  527. #ifdef KAA
  528.     if(unweapon) {
  529.         unweapon=FALSE;
  530.         if(uwep)
  531.             pline("You begin bashing monsters with your %s.",
  532.                 aobjnam(uwep,(char *)0));
  533.     }
  534. #endif
  535.     u_wipe_engr(3);   /* andrew@orca: prevent unlimited pick-axe attacks */
  536.  
  537.     if(mdat->mlet == 'L' && !mtmp->mfroz && !mtmp->msleep &&
  538.        !mtmp->mconf && mtmp->mcansee && !rn2(7) &&
  539.        (m_move(mtmp, 0) == 2 /* he died */ || /* he moved: */
  540.         mtmp->mx != u.ux+u.dx || mtmp->my != u.uy+u.dy))
  541.         return(FALSE);
  542. #ifdef SAFE_ATTACK
  543.     /* This section of code provides protection against accidentally
  544.      * hitting peaceful (like '@') and tame (like 'd') monsters.
  545.      * There is protection only if you're not blind, confused or
  546.      * invisible.
  547.      */
  548.     /*  changes by wwp 5/16/85 */
  549.     if (!Blind && !Confusion && !Hallucination
  550.         && mdat->mlet == 'd' && mtmp->mtame) {
  551.         char *dname;        /* added by Janet Walz (walz@mimsy) */
  552.         mtmp->mflee = 1;
  553.         mtmp->mfleetim = rnd(6);
  554.         if(*(dname = NAME(mtmp)))
  555.             pline("You stop to avoid hitting %s.",dname);
  556.         else
  557.             pline("You stop to avoid hitting your dog.");
  558.         return(TRUE);
  559.     }
  560.     if (flags.confirm && (mtmp->mpeaceful || mtmp->mtame) && ! Confusion
  561.         && !Hallucination && !Invisible)
  562.  
  563.         if (Blind ? Telepat : (!mtmp->minvis || See_invisible)) {
  564.             pline("Really attack %s?", monnam(mtmp));
  565.             (void) fflush(stdout);
  566.             if (readchar() != 'y') {
  567.                 flags.move = 0;
  568.                 return(TRUE);
  569.             }
  570.         }
  571. #endif /* SAFE_ATTACK /**/
  572.  
  573.     if(mtmp->mimic){
  574.         if(!u.ustuck && !mtmp->mflee) u.ustuck = mtmp;
  575.         if (levl[u.ux+u.dx][u.uy+u.dy].scrsym == DOOR_SYM)
  576.         {
  577.             if (okdoor(u.ux+u.dx, u.uy+u.dy))
  578.             pline("The door actually was %s.", defmonnam(mtmp));
  579.             else
  580.             pline("That spellbook was %s.", defmonnam(mtmp));
  581.         }
  582.         else if (levl[u.ux+u.dx][u.uy+u.dy].scrsym == GOLD_SYM)
  583.             pline("The chest was %s!", defmonnam(mtmp));
  584.         else
  585.             pline("Wait! That's %s!",defmonnam(mtmp));
  586.         wakeup(mtmp);   /* clears mtmp->mimic */
  587.         return(TRUE);
  588.     }
  589.  
  590.     wakeup(mtmp);
  591.  
  592.     if(mtmp->mhide && mtmp->mundetected){
  593.         register struct obj *obj;
  594.  
  595.         mtmp->mundetected = 0;
  596.         if((obj = o_at(mtmp->mx,mtmp->my)) && !Blind)
  597.             pline("Wait! There's %s hiding under %s!",
  598.                 defmonnam(mtmp), doname(obj));
  599.         return(TRUE);
  600.     }
  601. #ifdef KAA
  602.     tmp = u.uluck + (u.mtimedone ? mons[u.umonnum].mlevel : u.ulevel) +
  603.             mdat->ac + abon();
  604.     if (u.usym=='y' || u.usym=='F') tmp=100;
  605.     if (index("uEa",u.usym)) return(TRUE);
  606. #else
  607.     tmp = u.uluck + u.ulevel + mdat->ac + abon();
  608. #endif
  609.     if(uwep) {
  610. #ifdef KAA    /* Blessed weapons used against undead or demons */
  611.         if(uwep->olet == WEAPON_SYM && uwep->dknown && index("VWZ &",
  612.             mtmp->data->mlet)) tmp += 2;
  613. #endif
  614.         if(uwep->olet == WEAPON_SYM || uwep->otyp == PICK_AXE)
  615.             tmp += uwep->spe;
  616. #ifdef    BVH
  617.         if(!strcmp(ONAME(uwep),"Excalibur")) tmp += 5;
  618. #endif
  619.         if(uwep->otyp == TWO_HANDED_SWORD) tmp -= 1;
  620.         else if(uwep->otyp == KATANA) tmp += 1;
  621.         else if(uwep->otyp == DAGGER ||
  622.             uwep->otyp == SHURIKEN) tmp += 2;
  623.         else if(uwep->otyp == CRYSKNIFE) tmp += 3;
  624.         else if(uwep->otyp == SPEAR &&
  625.             index("XDne", mdat->mlet)) tmp += 2;
  626.     }
  627.     if(mtmp->msleep) {
  628.         mtmp->msleep = 0;
  629.         tmp += 2;
  630.     }
  631.     if(mtmp->mfroz) {
  632.         tmp += 4;
  633.         if(!rn2(10)) mtmp->mfroz = 0;
  634.     }
  635.     if(mtmp->mflee) tmp += 2;
  636.     if(u.utrap) tmp -= 3;
  637.  
  638.     /* with a lot of luggage, your agility diminishes */
  639.     tmp -= (inv_weight() + 40)/20;
  640.  
  641.     if(tmp <= rnd(20) && !u.uswallow){
  642.         if(Blind) pline("You miss it.");
  643.         else pline("You miss %s.",monnam(mtmp));
  644.     } else {
  645.         /* we hit the monster; be careful: it might die! */
  646.  
  647.         if((malive = hmon(mtmp,uwep,0)) == TRUE) {
  648.         /* monster still alive */
  649.             if(!rn2(25) && mtmp->mhp < mtmp->mhpmax/2) {
  650.                 mtmp->mflee = 1;
  651.                 if(!rn2(3)) mtmp->mfleetim = rnd(100);
  652.                 if(u.ustuck == mtmp && !u.uswallow)
  653.                     u.ustuck = 0;
  654.             }
  655. #ifndef NOWORM
  656.             if(mtmp->wormno)
  657.                 cutworm(mtmp, u.ux+u.dx, u.uy+u.dy,
  658.                     uwep ? uwep->otyp : 0);
  659. #endif
  660.         }
  661.         if(mdat->mlet == 'a') {
  662.             if(rn2(2)) {
  663.                 if (Blind) pline("You are splashed!");
  664.                 else       pline("You are splashed by %s's acid!",monnam(mtmp));
  665.                 if (u.usym != 'a') {
  666.                     losehp_m(rnd(6), mtmp);
  667.                     if(!rn2(30)) corrode_armor();
  668.                 }
  669.             }
  670.             if(!rn2(6)) corrode_weapon();
  671.         }
  672.     }
  673. #ifdef KAA
  674.     if (malive) if (u.usym=='N' && mtmp->minvent) {
  675.         struct obj *otmp, *addinv();
  676.         otmp = mtmp->minvent;
  677.         mtmp->minvent = otmp->nobj;
  678.         otmp = addinv(otmp);
  679.         pline("You steal:");
  680.         prinv(otmp);
  681.     } else if (u.usym=='L' && mtmp->mgold) {
  682.         u.ugold += mtmp->mgold;
  683.         mtmp->mgold = 0;
  684.         pline("Your purse feels heavier.");
  685.     } else if (u.usym=='Q') rloc(mtmp);
  686. #endif
  687.     if(malive && mdat->mlet == 'E' && canseemon(mtmp)
  688.        && !mtmp->mcan && rn2(3)) {
  689.         if(mtmp->mcansee) {
  690.           pline("You are frozen by %s's gaze!",monnam(mtmp));
  691.           nomul((u.ulevel > 6 || rn2(4)) ? rn1(20,-21) : -200);
  692.         } else {
  693.           pline("%s cannot defend itself.", Amonnam(mtmp,"blinded"));
  694.           if(!rn2(500)) change_luck(-1);
  695.         }
  696.     }
  697.     return(TRUE);
  698. }
  699.  
  700. #ifdef STOOGES
  701. stoogejoke() {          /* have the stooges say something funny */
  702.     pline("'%s'", random_joke[rn2(RAND_JOKE)]);
  703. }
  704. #endif
  705.